﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using HellaDotNet.XmlRPC;

namespace HellaDotNet.GUI
{
    public partial class FormMain : Form
    {
        private Connection _Connection;

        public FormMain()
        {
            InitializeComponent();

            this.ResetConnection();
        }

        private void ResetConnection()
        {
            this._Connection = new Connection(Properties.Settings.Default.Uri, Properties.Settings.Default.Username, Properties.Settings.Default.Password);
            this._Connection.ConnectionStatusChanged += new ConnectionStatusChangedDelegate(ConnectionStatusChanged);
            this.ProcessStatusObject(this._Connection.GetStatus());
        }

        private void ConnectionStatusChanged(object sender, ConnectionStatusEventArgs e)
        {
            switch (e.ConnectionStatus)
            {
                case Connection.ConnectionStatus.Success:
                    this.labelStatus.BackColor = Color.Green;
                    break;
                case Connection.ConnectionStatus.Busy:
                    this.labelStatus.BackColor = Color.Orange;
                    break;
                case Connection.ConnectionStatus.Failed:
                    this.labelStatus.BackColor = Color.Red;
                    break;
            }
        }

        private void ProcessStatusObject(Status status)
        {
            if (listViewNzbFiles.Items.Count == 0)
            {
                foreach (NzbFile nzb in status.NzbFiles)
                {
                    listViewNzbFiles.Items.Add(new ListViewItem(new string[] { nzb.Id.ToString(), nzb.Name, nzb.Size.ToString(), nzb.Status.ToString() }));
                }
            }
            else
            {
                NzbFile file;

                foreach (ListViewItem item in listViewNzbFiles.Items)
                {
                    file = status.NzbFiles.FindById(Convert.ToInt32(item.SubItems[0].Text));
                    if (file != null)
                    {
                        if (item.SubItems[3].Text != file.Status.ToString())
                            item.SubItems[3].Text = file.Status.ToString();

                        if (item.SubItems[2].Text != file.Size.ToString())
                            item.SubItems[2].Text = file.Size.ToString();

                        file.Id = -1;
                    }
                    else
                    {
                        listViewNzbFiles.Items.Remove(item);
                    }
                }
                foreach (NzbFile nzb in status.NzbFiles)
                {
                    if (nzb.Id != -1)
                    {
                        listViewNzbFiles.Items.Add(new ListViewItem(new string[] { nzb.Id.ToString(), nzb.Name, nzb.Size.ToString(), nzb.Status.ToString() }));
                    }
                }
            }


            label1.Text = status.PercentageCompleted.ToString();
            label2.Text = status.DownloadRate.ToString();
            label3.Text = status.Eta.ToString();

            ////Set Pause button
            this.toolStripButtonPause.Checked = status.IsPaused;

            
        }

        

        private void timerConnection_Tick(object sender, EventArgs e)
        {
            this.ProcessStatusObject(this._Connection.GetStatus());
        }

        private void toolStripButtonPause_Click(object sender, EventArgs e)
        {
            if (this.toolStripButtonPause.Checked)
                this.ProcessStatusObject(this._Connection.Pause());
            else
                this.ProcessStatusObject(this._Connection.Continue());
        }


        private Rectangle dragBoxFromMouseDown;
        private int rowIndexFromMouseDown;
        private int rowIndexOfItemUnderMouseToDrop;

        private void listViewNzbFiles_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (dragBoxFromMouseDown != Rectangle.Empty && !dragBoxFromMouseDown.Contains(e.X, e.Y))
                {
                    DragDropEffects dropEffect = listViewNzbFiles.DoDragDrop(listViewNzbFiles.Items[rowIndexFromMouseDown], DragDropEffects.Move);
                }
            }
        }

        private void listViewNzbFiles_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                ListViewItem item = listViewNzbFiles.HitTest(e.X, e.Y).Item;
                if (item != null)
                {
                    rowIndexFromMouseDown = item.Index;
                    if (rowIndexFromMouseDown != -1)
                    {
                        Size dragSize = SystemInformation.DragSize;
                        dragBoxFromMouseDown = new Rectangle(new Point(e.X - (dragSize.Width / 2), e.Y - (dragSize.Height / 2)), dragSize);
                    }
                    else
                        dragBoxFromMouseDown = Rectangle.Empty;
                }
            }
        }

        private void listViewNzbFiles_DragOver(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Move;
            
            this.pictureBoxPosition.Width = this.listViewNzbFiles.Width - 4;
            this.pictureBoxPosition.Left = this.listViewNzbFiles.Left + 2;

            Point clientPoint = listViewNzbFiles.PointToClient(new Point(e.X, e.Y));
            ListViewItem item = listViewNzbFiles.HitTest(clientPoint.X, clientPoint.Y).Item;

            if (item == null)
            {
                item = listViewNzbFiles.Items[listViewNzbFiles.Items.Count - 1];
            }

            Int32 position = item.Position.Y + 1;
            this.pictureBoxPosition.Top = this.listViewNzbFiles.Top + position;

            this.pictureBoxPosition.Visible = true;
        }

        private void listViewNzbFiles_DragDrop(object sender, DragEventArgs e)
        {
            this.pictureBoxPosition.Visible = false;

            Point clientPoint = listViewNzbFiles.PointToClient(new Point(e.X, e.Y));
            ListViewHitTestInfo info = listViewNzbFiles.HitTest(clientPoint.X, clientPoint.Y);
            if (info.Item == null)
            {
                rowIndexOfItemUnderMouseToDrop = listViewNzbFiles.Items.Count - 1;
            }
            else
            {
                rowIndexOfItemUnderMouseToDrop = info.Item.Index;
            }
            if (e.Effect == DragDropEffects.Move)
            {
                ListViewItem rowToMove = (ListViewItem)e.Data.GetData(typeof(ListViewItem));
                listViewNzbFiles.Items.RemoveAt(rowIndexFromMouseDown);
                listViewNzbFiles.Items.Insert(rowIndexOfItemUnderMouseToDrop, rowToMove);

                int newRow = 0;
                for (int i = 0; i < rowIndexOfItemUnderMouseToDrop; i++)
                {
                    newRow++;
                }

                if (newRow == 0)
                {

                    this.ProcessStatusObject(this._Connection.Force(Convert.ToInt32(rowToMove.Text)));
                }
                else
                {
                    if (rowIndexFromMouseDown == 0)
                    {
                        this.ProcessStatusObject(this._Connection.Force(Convert.ToInt32(listViewNzbFiles.Items[0].Text)));
                    }
                    this._Connection.Move(Convert.ToInt32(rowToMove.Text), newRow);
                }
                
            }
        }

        private void FormMain_Load(object sender, EventArgs e)
        {

        }
    }
}
